package com.dq.ali.pay;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.dq.ali.pay.properties.AliPayProperties;
import com.dq.utils.QrUtils;
import com.dq.utils.SpringUtil;
import com.dq.wx.pay.WxPayUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.InputStream;
import java.math.BigDecimal;

public class AliPayUtils {
    /**
     * 获取 阿里 支付 配置参数
     */
    private static final AliPayProperties aliPayProperties = SpringUtil.getBean(AliPayProperties.class);
    /**
     * 初始化 AlipayClient
     */
    private static AlipayClient alipayClient;

    public static AlipayClient getAlipayClient() {
        if (alipayClient == null) {
            alipayClient = new DefaultAlipayClient(aliPayProperties.getUrl(), aliPayProperties.getAppid(), aliPayProperties.getAppPrivateKey(),
                    aliPayProperties.getFormat(), aliPayProperties.getCharset(), aliPayProperties.getAlipayPublicKey(), aliPayProperties.getSignType());
        }
        return alipayClient;
    }

    /**
     * 扫码支付: 预下单
     *
     * @param outTradeNo     商户订单号,64个字符以内、只能包含字母、数字、下划线；需保证在商户端不重复
     * @param totalAmount    订单总金额，单位为 [元]， 精确到小数点后两位，取值范围[0.01,100000000] 如果同时传入了【打折金额】，【不可打折金额】，【订单总金额】三者，则必须满足如下条件：【订单总金额】=【打折金额】+【不可打折金额】
     * @param subject        订单标题, STRING(256)
     * @param timeoutExpress 该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
     * @param productId      用来 [用户ID+商品ID命名]命名交易会话二维码, 保证一个用户一个商品只会有一个名字的二维码
     * @param loginUserId    用来 [用户ID+商品ID命名]命名交易会话二维码, 保证一个用户一个商品只会有一个名字的二维码
     */
    public static String precreate(String outTradeNo, BigDecimal totalAmount, String subject, String timeoutExpress, String productId, Long loginUserId) throws AlipayApiException {
        // 创建API对应的request类
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        JSONObject json = new JSONObject();
        json.put("out_trade_no", outTradeNo);
        json.put("total_amount", totalAmount);
        json.put("subject", subject);
        // 支付结果 异步通知地址
        json.put("notify_url", aliPayProperties.getNotifyUrl());

        if (StringUtils.isNotBlank(timeoutExpress)) {
            json.put("timeout_express", timeoutExpress);
        }
        request.setBizContent(json.toJSONString());
//        request.setBizContent("{" +
//                "    \"store_id\":\"NJ_001\"," +
//                "    \"timeout_express\":\"90m\"}");//订单允许的最晚付款时间

        AlipayTradePrecreateResponse response = getAlipayClient().execute(request);
        JSONObject jsonResponse = JSONObject.parseObject(response.getBody());
        System.out.println("支付宝响应数据: " + jsonResponse);

        JSONObject precreate = jsonResponse.getJSONObject("alipay_trade_precreate_response");
        String code = precreate.getString("code");
        if ("10000".equals(code)) {
            String sign = jsonResponse.getString("sign");
            String qrUrl = precreate.get("qr_code").toString();
            // qruRL -> InputStream
            InputStream in = QrUtils.makeQrCode(qrUrl, 400, 400);
            // 根据返回二维码URL, 生成图片, 保存到OSS, 同时保存一些信息到订单
            String ossQrUrl = WxPayUtils.qrUrl2oss(outTradeNo, productId, loginUserId, sign, in);

            return ossQrUrl;
        } else {
            throw new RuntimeException("[支付宝 - 扫码支付(预下单) - 异常] msg: " + precreate);
        }
    }

    /**
     * 查询交易: 订单支付结果查询
     *
     * @param outTradeNo 支付时传入的商户订单号，与 trade_no 必填一个
     */
    public static JSONObject query(String outTradeNo) throws AlipayApiException {
        // 创建API对应的request类
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject json = new JSONObject();
        json.put("out_trade_no", outTradeNo);

        request.setBizContent(json.toJSONString());
//        request.setBizContent("{" +
//                "    \"out_trade_no\":\"20150320010101001\"," +
//                "    \"trade_no\":\"2014112611001004680073956707\"}"); //设置业务参数
        // 通过alipayClient调用API，获得对应的response类

        AlipayTradeQueryResponse response = getAlipayClient().execute(request);
        JSONObject jsonResponse = JSONObject.parseObject(response.getBody());
        System.out.println("支付宝响应数据: " + jsonResponse);

        JSONObject precreate = jsonResponse.getJSONObject("alipay_trade_query_response");
        String code = precreate.getString("code");
        if ("10000".equals(code)) {
            String sign = jsonResponse.getString("sign");
            precreate.put("sign", sign);
            return precreate;
        } else {
            throw new RuntimeException("[支付宝 - 查询交易(订单支付结果查询) - 异常] msg: " + precreate);
        }
    }

}
